/*
 * Copyright (C) 2011 ARNDroid
 * 
 * Licensed under the Apache License, Version 2.0 (the "License"); you may not
 * use this file except in compliance with the License. You may obtain a copy of
 * the License at
 * 
 * http://www.apache.org/licenses/LICENSE-2.0
 * 
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
 * License for the specific language governing permissions and limitations under
 * the License.
 */
package br.com.arndroid.lib.entity;

import android.database.Cursor;
import br.com.arndroid.lib.validation.ConstraintViolations;

/**
 * The controller interface for entities.
 *
 * <p>
 * This interface define operations format for CRUD with a
 * {@link EntityPOJO} subclass type parameter.
 * </p>
 * <p>
 * There are <a href="#Preconditions">preconditions</a> for using this interface.
 * </p>
 *
 * <a name="Preconditions"></a>
 * <h4>Preconditions</h4>
 * <p>
 * The creation of a related {@link EntityPOJO} subclass.
 * </p>
 *
 * @author Alceu Rodrigues Neto
 * @param <T> the {@link EntityPOJO} to be controlled
 */
public interface EntityController<T extends EntityPOJO> {
	
	/**
	 * Persist the POJO. Semantically the POJO may be already
	 * validated and the need of persistence already checked.
	 * 
	 * @param pojo the pojo to be persisted
	 * @return the _id of new or updated POJO
	 * @see {@link #isPersistable}
	 * @see {@link #validate}
	 */
	public long persist(T pojo);
	
	/**
	 * Return {@code true} if a persist operation may be executed for the POJO.
	 * <p>
	 * A simple implementation allways returns {@code true}, but in a expensive persist
	 * operation, may be a good practic see if the POJO is not already persisted and with
	 * no updates.
	 * 
	 * @param pojo the POJO to be evaluated
	 * @return {@code true} if a persist operation may be executed, otherwhise {@code false}
	 */
	public boolean isPersistable(T pojo);
	
	/**
	 * Validate the POJO and return the violations or {@code null} if there are no violations.
	 * 
	 * @param pojo the POJO to be validated
	 * @return violations or {@code null}
	 */
	public ConstraintViolations validate(T pojo);
	
	/**
	 * Return a cursor with all persisted entities. If there are no persisted entities,
	 * a empty cursor is returned. 
	 * 
	 * @return a cursor with all persisted entities
	 */
	public Cursor getAll();
	
	/**
	 * Remove the entity with the informed id. Semantically a try to remove a inexistent id
	 * represent a illegal operation.
	 * 
	 * @param id the id of the entity to be removed
	 */
	public void remove(long id);
	
	/**
	 * Return the entity represented by informed id. Semantically a try to get a inexistent id
	 * represent a illegal operation.
	 * 
	 * @param id the id of entity to be get
	 * @return the entity
	 */
	public T getById(long id);
}
